﻿using System;
using UnityEngine;

namespace ZyGame.Game
{
    public interface IListenerDeviceInputChannel : IDisposable
    {
        float GetHorizontal();
        float GetVertical();
        bool GetKeyDown(KeyCode keyCode);
        bool GetKey(KeyCode keyCode);
        bool GetKeyUp(KeyCode keyCode);
    }

    /// <summary>
    /// 玩家输入组件
    /// </summary>
    public class InputLinstenerComponent : EntityComponent
    {
        protected Camera camera;
        protected FSMComponent fSMComponent;
        protected TransformComponent transformComponent;
        protected CharacterController characterController;
        private IListenerDeviceInputChannel _deviceInputChannel;
        private Vector3 offset;

        public override void Awake(params object[] dataList)
        {
            this.camera = dataList.GetAndCast<Camera>();
            this._deviceInputChannel = dataList.GetAndCast<IListenerDeviceInputChannel>();
            fSMComponent = entity.GetComponent<FSMComponent>();
            transformComponent = entity.GetComponent<TransformComponent>();
            characterController = transformComponent.gameObject.GetComponent<CharacterController>();
            offset = camera.transform.position - transformComponent.transform.position;
            Client.Tools.AddUpdate(Execute);
        }

        public override void Dispose()
        {
            base.Dispose();
            Client.Tools.RemoveCallback(Execute);
            characterController = null;
            transformComponent = null;
            fSMComponent = null;
            camera = null;
        }

        protected virtual void Execute()
        {
            float h = _deviceInputChannel.GetHorizontal();
            float v = _deviceInputChannel.GetVertical();
            if (v is 0 && h is 0)
            {
                fSMComponent.Switch<NoneState>();
                return;
            }

            Vector3 targetDirection = new Vector3(h, 0, v);

            if (fSMComponent.Switch<RunState>())
            {
                float y = camera.transform.rotation.eulerAngles.y;
                targetDirection = Quaternion.Euler(0, y, 0) * targetDirection;
                transformComponent.rotation = new Vector3(transformComponent.rotation.x, camera.transform.rotation.eulerAngles.y, transformComponent.rotation.z);
            }
            else
            {
                float y = camera.transform.rotation.eulerAngles.y;
                targetDirection = Quaternion.Euler(0, y, 0) * targetDirection;
                Vector3 dir = transformComponent.position + targetDirection;
                transformComponent.transform.LookAt(dir, transformComponent.transform.up);
                // float y = transformComponent.rotation.y;
                // targetDirection = Quaternion.Euler(0, y, 0) * targetDirection;
            }

            // moved = new Vector3(h, 0, v) * 2.5f;
            // Vector3 p = camera.transform.position - offset + camera.transform.forward;
            // transformComponent.transform.Rotate(new Vector3(transformComponent.rotation.x, camera.transform.rotation.eulerAngles.y, transformComponent.rotation.z));


            characterController.SimpleMove(targetDirection * 2f);
        }

        class CustomDiveceInputListener : IListenerDeviceInputChannel
        {
            public void Dispose()
            {
            }

            public float GetHorizontal()
            {
                return Input.GetAxis("Horizontal");
            }

            public float GetVertical()
            {
                return Input.GetAxis("Vertical");
            }

            public bool GetKeyDown(KeyCode keyCode)
            {
                return Input.GetKeyDown(keyCode);
            }

            public bool GetKey(KeyCode keyCode)
            {
                return Input.GetKey(keyCode);
            }

            public bool GetKeyUp(KeyCode keyCode)
            {
                return Input.GetKeyUp(keyCode);
            }
        }
    }
}